package edu.osu.cse.c651.cryptochess;

import java.io.IOException;
import java.net.UnknownHostException;

import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

/**
 * Intermediary between the view (GameActivity) and the model (ChessBoard)
 * 
 * @author Team Pawned
 * 
 */
public class BoardController {

	/**
	 * The view, or user-interface. The user interacts with it to change the
	 * model, and this BoardController communicates between the two.
	 */
	private GameActivity view;

	/**
	 * The model represents the state of the current match. The display of user
	 * interface depends on it.
	 */
	private ChessBoard model;

	/**
	 * Represents the player of the game, or the user.
	 */
	private Player player;

	/**
	 * The color of this player's pieces, white or black.
	 */
	private Color playerColor;

	/**
	 * Used by the ChessImageListener class to determine state while a Player is
	 * making his move
	 */
	private int piecesSelected;

	/**
	 * Used by the ChessImageListener class to store the row of the square of
	 * the Piece to be moved
	 */
	private int x1;

	/**
	 * Used by the ChessImageListener class to store the column of the square of
	 * the Piece to be moved
	 */
	private int y1;

	/**
	 * Used by the ChessImageListener class to store the row of the square to
	 * which an attempted move will be made
	 */
	private int x2;

	/**
	 * Used by the ChessImageListener class to store the column of the square to
	 * which an attempted move will be made
	 */
	private int y2;

	/**
	 * Used for debugging
	 */
	public static String TAG = "BoardController";

	/**
	 * This controller ties together the model (the state of the ChessBoard and
	 * this Player) and the View (the User interface).
	 * 
	 * @param view
	 *            GameActivity the user interface
	 * @param model
	 *            ChessBoard the state of the chess board and match
	 * @param player
	 *            Player this player
	 */
	public BoardController(GameActivity view, ChessBoard model, Player player) {
		this.view = view;
		this.model = model;
		this.player = player;
		this.playerColor = player.color();
		piecesSelected = 0;
		Log.d(TAG, "About to add listeneres");
		for (int i = 0; i < 8; i++) {
			for (int k = 0; k < 8; k++) {
				view.addSquareListener(view.squares[i][k],
						new ChessImageListener(view.squares[i][k]));
			}
		}
		Log.d(TAG, "Added listeners");
		x1 = 0;
		y1 = 0;
		x2 = 0;
		y2 = 0;
		paintScreen();
	}

	/**
	 * Paints the user interface with the model's board
	 */
	private void paintScreen() {
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {
				view.paint(x, y, model.getPiece(x, y));
			}
		}
	}

	/**
	 * Loads the supplied board into the model and paints the user interface's
	 * board with it. Called when this user receives the board from the
	 * opponent, after he has moved.
	 * 
	 * @param board
	 *            ChessBoard the new board to be used
	 * @throws IOException
	 *             I/O exception
	 * @throws UnknownHostException
	 */
	public void loadBoard(ChessBoard board) throws UnknownHostException,
			IOException {
		model = board;
		paintScreen();
		if (board.endGame()) {
			// TODO display result
			view.endGame();
			return;
		}
		piecesSelected = 0;
		if (model.getCapturedPiece() != null) {
			player.addCapturedPiece(model.getCapturedPiece());
		}
	}

	/**
	 * This listener will reside on each square of the chess board of the user
	 * interface. Its onClick method changes the state (the ChessBoard).
	 * 
	 * @author Dan
	 * 
	 */
	private class ChessImageListener implements ImageView.OnClickListener {

		/**
		 * The SquareContainer representing the square on the GUI chess board
		 * that will host this ChessImageListener
		 */
		private SquareContainer sq;

		/**
		 * Used to change the model as the GUI is being changed by the user
		 * 
		 * @param sq
		 *            SquareContainter the square on the chess board
		 */
		public ChessImageListener(SquareContainer sq) {
			this.sq = sq;
		}

		/**
		 * Instructions on how to change the model as different chess board
		 * pieces are being clicked
		 */
		public void onClick(View v) {

			Log.d(TAG, "onClick being read");

			if (piecesSelected == 0) {
				x1 = sq.x();
				y1 = sq.y();
				if (model.getPiece(x1, y1) == null) {
					// do nothing
					Log.d(TAG, "empty square selected");
				} else if (!model.correctPlayerSelected(playerColor, x1, y1)) {
					// Display error something
					Log.d(TAG, "Wrong piece selected");
				} else {
					piecesSelected = 1;
					Log.d(TAG, "Correct piece selected");
					// Display that the piece is selected

					// view.paint(x, y, model.getPiece(x, y));
				}
			} else {
				x2 = sq.x();
				y2 = sq.y();
				Log.d(TAG, "Trying to move piece");
				
				Coordinate king = ChessBoard.findKing(playerColor, model);
				Status gameStatus = ChessBoard.inMate(playerColor, model, king.x, king.y);
				
				// Checks game status for either checkmate or stalemate
				if (gameStatus == Status.CHECKMATE) {
					model.setEndGame(true);
					if (playerColor == Color.WHITE) {
						model.setWinner(Winner.BLACK);
					} else {
						model.setWinner(Winner.WHITE);
					}
				} else if (gameStatus == Status.STALEMATE) {
					model.setEndGame(true);
					model.setWinner(Winner.STALEMATE);
				}
				if (model.move(playerColor, x1, y1, x2, y2)) {
					try {
						Log.d(TAG, "Right before move execution");
						model.executeMove(x1, y1, x2, y2);
						Log.d(TAG, "Right after move execution");
					} catch (Exception e) {
						System.err.println(e.getMessage());
					}

					/*
					 * if( model.pawnReachedEnd() ) { Piece insert =
					 * view.pawnReachedEnd_SwitchInPiece(
					 * player.capturedPieces() );
					 * model.pawnReachedEnd_SwitchInPiece(insert,
					 * model.arrivedPawnX(), model.arrivedPawnY()); }
					 */

					Log.d(TAG, "Right before paintScreen");
					paintScreen();
					Log.d(TAG, "Right after paintScreen");

					piecesSelected = 2;

					view.sendBoard(model);
				} else {
					piecesSelected = 0;
				}
			}

			String id;
			switch (v.getId()) {
			case R.id.tile_a1:
				id = "A1";
				break;
			case R.id.tile_a2:
				id = "A2";
				break;
			case R.id.tile_a3:
				id = "A3";
				break;
			case R.id.tile_a4:
				id = "A4";
				break;
			case R.id.tile_a5:
				id = "A5";
				break;
			case R.id.tile_a6:
				id = "A6";
				break;
			case R.id.tile_a7:
				id = "A7";
				break;
			case R.id.tile_a8:
				id = "A8";
				break;
			case R.id.tile_b1:
				id = "B1";
				break;
			case R.id.tile_b2:
				id = "B2";
				break;
			case R.id.tile_b3:
				id = "B3";
				break;
			case R.id.tile_b4:
				id = "B4";
				break;
			case R.id.tile_b5:
				id = "B5";
				break;
			case R.id.tile_b6:
				id = "B6";
				break;
			case R.id.tile_b7:
				id = "B7";
				break;
			case R.id.tile_b8:
				id = "B8";
				break;
			case R.id.tile_c1:
				id = "C1";
				break;
			case R.id.tile_c2:
				id = "C2";
				break;
			case R.id.tile_c3:
				id = "C3";
				break;
			case R.id.tile_c4:
				id = "C4";
				break;
			case R.id.tile_c5:
				id = "C5";
				break;
			case R.id.tile_c6:
				id = "C6";
				break;
			case R.id.tile_c7:
				id = "C7";
				break;
			case R.id.tile_c8:
				id = "C8";
				break;
			case R.id.tile_d1:
				id = "D1";
				break;
			case R.id.tile_d2:
				id = "D2";
				break;
			case R.id.tile_d3:
				id = "D3";
				break;
			case R.id.tile_d4:
				id = "D4";
				break;
			case R.id.tile_d5:
				id = "D5";
				break;
			case R.id.tile_d6:
				id = "D6";
				break;
			case R.id.tile_d7:
				id = "D7";
				break;
			case R.id.tile_d8:
				id = "D8";
				break;
			case R.id.tile_e1:
				id = "E1";
				break;
			case R.id.tile_e2:
				id = "E2";
				break;
			case R.id.tile_e3:
				id = "E3";
				break;
			case R.id.tile_e4:
				id = "E4";
				break;
			case R.id.tile_e5:
				id = "E5";
				break;
			case R.id.tile_e6:
				id = "E6";
				break;
			case R.id.tile_e7:
				id = "E7";
				break;
			case R.id.tile_e8:
				id = "E8";
				break;
			case R.id.tile_f1:
				id = "F1";
				break;
			case R.id.tile_f2:
				id = "F2";
				break;
			case R.id.tile_f3:
				id = "F3";
				break;
			case R.id.tile_f4:
				id = "F4";
				break;
			case R.id.tile_f5:
				id = "F5";
				break;
			case R.id.tile_f6:
				id = "F6";
				break;
			case R.id.tile_f7:
				id = "F7";
				break;
			case R.id.tile_f8:
				id = "F8";
				break;
			case R.id.tile_g1:
				id = "G1";
				break;
			case R.id.tile_g2:
				id = "G2";
				break;
			case R.id.tile_g3:
				id = "G3";
				break;
			case R.id.tile_g4:
				id = "G4";
				break;
			case R.id.tile_g5:
				id = "G5";
				break;
			case R.id.tile_g6:
				id = "G6";
				break;
			case R.id.tile_g7:
				id = "G7";
				break;
			case R.id.tile_g8:
				id = "G8";
				break;
			case R.id.tile_h1:
				id = "H1";
				break;
			case R.id.tile_h2:
				id = "H2";
				break;
			case R.id.tile_h3:
				id = "H3";
				break;
			case R.id.tile_h4:
				id = "H4";
				break;
			case R.id.tile_h5:
				id = "H5";
				break;
			case R.id.tile_h6:
				id = "H6";
				break;
			case R.id.tile_h7:
				id = "H7";
				break;
			case R.id.tile_h8:
				id = "H8";
				break;
			default:
				id = "unkown";
				break;
			}

			Log.d(TAG, "id clicked: " + id);
		}
	}

}